home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Magazin: Amiga-CD 1996 May & June
/
Amiga-CD 1996 #5-6.iso
/
kommunikation
/
ipdial
/
ipdial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-22
|
23KB
|
1,135 lines
/**
*** IPDial Script program for initializing a SLIP connection
*** Copyright (C) 1994 Jochen Wiedmann
***
*** This program is free software; you can redistribute it and/or modify
*** it under the terms of the GNU General Public License as published by
*** the Free Software Foundation; either version 2 of the License, or
*** (at your option) any later version.
***
*** This program is distributed in the hope that it will be useful,
*** but WITHOUT ANY WARRANTY; without even the implied warranty of
*** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*** GNU General Public License for more details.
***
*** You should have received a copy of the GNU General Public License
*** along with this program; if not, write to the Free Software
*** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***
***
*** This is the main part of the program.
***
***
*** Computer: Amiga 1200 Compiler: Dice 3.01
***
*** Author: Jochen Wiedmann
*** Am Eisteich 9
*** 72555 Metzingen
*** Germany
***
*** Phone: (+0049) 7123 / 14881
*** Internet: wiedmann@neckar-alb.de
***
***
*** History: V 1.1 23.11.94 Initial version
***
*** V 1.2 27.02.95 Added terminal mode
*** Now using ReadArgs() for
*** command line parsing.
***
*** V 1.3 09.03.95 Added environment variable
*** aupport to "send" command.
*** Added unit support.
***
*** V 1.4 21.04.95 Added "system" command.
*** Added environment variable
*** support to "echo" command.
*** Terminal mode now converts
*** LF to CR/LF, so that modem
*** recognizes commands.
*** (Let's hope, that will still
*** work for entering passwords. :-(
***
*** V 1.5 30.04.95 Added "scan" command.
***
*** V 1.6 26.06.95 "delay" command supporting
*** ticks; ParseString()
*** supporting octal characters;
*** "wait" command using
*** ParseString()
*** (All Suggested by Will Bow.)
***
*** Fixed bug in SerialSend():
*** *.io_Device = *.io_Unit
***
*** V 1.7 22.07.95 Added ECHO, RAW and EOF options
*** to "terminal" command.
*** (Suggested by Klaus Heinz.)
***
*** Added BAUD option to command
*** line.
***
*** Added "setvar" command.
**/
#define VERSION 1
#define REVISION 7
#define VSTRING "IPDial 1.7 (22.07.95)"
#define VERSTAG "\0$VER: IPDial 1.7 (22.07.95)"
/**
*** Include files
**/
#ifndef IPDIAL_H
#include "IPDial.h"
#endif
#include <ctype.h>
#include <clib/alib_protos.h>
/**
*** This structure describes one command. All commands are stored
*** in a table at the end of the file.
**/
struct ScriptLine;
typedef VOID (*CommandFunc) (struct ScriptLine *);
struct Command
{ CommandFunc Func;
STRPTR Name;
};
/**
*** Each line of the script file is stored in a structure like below.
**/
struct ScriptLine
{ struct MinNode mn;
ULONG Num;
CommandFunc CommFunc;
STRPTR Label;
STRPTR Args;
};
/**
*** Global variables
**/
LONG StatusVar;
struct MinList ScriptLineList;
struct ScriptLine *CurrentScriptLine;
const UBYTE VersTag [] = VERSTAG;
const UBYTE VString [] = VSTRING;
ULONG EchoMode = FALSE;
ULONG VerboseMode = FALSE;
STRPTR SerialDeviceName = NULL;
struct RDArgs *MainRDArgs = NULL;
/**
*** This function is used to skip blanks.
**/
STRPTR SkipBlanks(const UBYTE *ptr)
{ while(*ptr == ' ' || *ptr == '\t')
{ ++ptr;
}
return((STRPTR) ptr);
}
/**
*** This function is used to parse a string for characters
*** like '\r' or '\n'. $VAR or ${VAR} may be used to insert
*** the value of environment variable VAR, $$ may be used to
*** insert the '$' character itself, likewise \\.
***
*** Returns a pointer to a string allocated with malloc().
*** It is the task of the caller, to free() this string.
**/
STRPTR ParseString(const UBYTE *ptr)
{ STRPTR result;
STATIC APTR parseBuffer = NULL;
/**
*** Be sure, that buffer is valid.
**/
if (!parseBuffer && !(parseBuffer = BufferCreate()))
{ perror("malloc");
exit(10);
}
/**
*** Clear the buffer.
**/
BufferClear(parseBuffer);
while(*ptr)
{ if (*ptr == '\\')
{ ++ptr;
switch(*ptr)
{ case 'r':
BufferExtend(parseBuffer, (STRPTR) "\r", 1);
break;
case 'n':
BufferExtend(parseBuffer, (STRPTR) "\n", 1);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{ char c;
c = *ptr - '0';
if (ptr[1] >= '0' && ptr[1] <= '7')
{ c = (c << 3) + *(++ptr) - '0';
if (ptr[1] >= '0' && ptr[2] <= '7')
{ c = (c << 3) + *(++ptr) - '0';
}
}
BufferExtend(parseBuffer, (STRPTR) &c, 1);
}
break;
default:
BufferExtend(parseBuffer, ptr, 1);
break;
}
++ptr;
}
else if (*ptr == '$')
{ ++ptr;
if (*ptr == '$')
{ BufferExtend(parseBuffer, (STRPTR) "$", 1);
++ptr;
}
else
{ char *varName;
const char* varPtr;
size_t varLen = 0;
if (*ptr == '{')
{ ++ptr;
varPtr = (const char*) ptr;
while (*ptr && *ptr != '}')
{ ++ptr;
++varLen;
}
if (*ptr == '}')
{ ++ptr;
}
}
else
{ varPtr = (const char*) ptr;
while (*ptr && isalnum(*ptr))
{ ++ptr;
++varLen;
}
}
if (!(varName = malloc(varLen + 1)))
{ perror("malloc");
exit(10);
}
strncpy(varName, varPtr, varLen);
varName[varLen] = '\0';
if ((varPtr = getenv(varName)))
{ BufferExtend(parseBuffer, (STRPTR) varPtr, strlen(varPtr));
}
}
}
else
{ BufferExtend(parseBuffer, ptr, 1);
++ptr;
}
}
BufferExtend(parseBuffer, (STRPTR) "", 1);
if (!(result = (STRPTR) strdup((char*) BufferBuffer(parseBuffer))))
{ perror("malloc");
exit(10);
}
return(result);
}
/**
*** This is an empty function. Just to allow lines with labels only.
**/
VOID NoneFunc(struct ScriptLine *line)
{
}
/**
*** This is the echo function.
**/
VOID EchoFunc(struct ScriptLine *line)
{ STRPTR *args;
int i;
if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
{ fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
exit(10);
}
for(i = 0; *args; ++i, ++args)
{ char *str;
if (i)
{ putchar(' ');
}
str = (char*) ParseString(*args);
fputs((char *) str, stdout);
fflush(stdout);
free(str);
}
}
/**
*** This is the device function.
**/
VOID DeviceFunc(struct ScriptLine *line)
{ struct
{ STRPTR Device;
STRPTR Protocol;
LONG *Unit;
} args;
if (SerialDeviceName)
{ fprintf(stderr, "Line %ld: Device already open, ignoring.\n", line->Num);
}
args.Unit = NULL;
args.Device = NULL;
args.Protocol = NULL;
if (!StrReadArgs(line->Args, (LONG *) &args,
(STRPTR) "DEVICE,PROTOCOL,UNIT/K/N"))
{ fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
exit(10);
}
if (!args.Device)
{ fprintf(stderr, "Line %ld: Missing device name.\n", line->Num);
exit(10);
}
if (!(SerialDeviceName = (STRPTR) strdup((char *) args.Device)))
{ perror("malloc");
exit(10);
}
if (VerboseMode)
{ printf("Opening %s.\n", args.Device);
}
if (!SerialOpen(args.Device, args.Protocol, args.Unit ? *args.Unit : 0))
{ fprintf(stderr, "Line %ld: Unknown protocol.\n", line->Num);
exit(10);
}
}
/**
*** This function is used to set the serial.device parameters.
**/
VOID SetFunc(struct ScriptLine *line)
{ struct
{ ULONG *Baud;
ULONG *DataBits;
ULONG *StopBits;
ULONG *BufSize;
STRPTR Parity;
STRPTR Protocol;
} args;
if (!SerialDeviceName)
{ fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
exit(10);
}
args.Baud = NULL;
args.DataBits = NULL;
args.StopBits = NULL;
args.BufSize = NULL;
args.Parity = NULL;
args.Protocol = NULL;
if (!(StrReadArgs(line->Args, (LONG *) &args,
(STRPTR) "BAUD/K/N,DATABITS/K/N,STOPBITS/K/N,BUFSIZE/K/N,"
"PARITY/K,PROTOCOL/K")))
{ fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
exit(10);
}
if (args.Baud)
{ SerialSetBaud(*args.Baud);
}
if (args.DataBits)
{ SerialSetDataBits(*args.DataBits);
}
if (args.StopBits)
{ SerialSetStopBits(*args.StopBits);
}
if (args.BufSize)
{ SerialSetBufSize(*args.BufSize);
}
if (args.Parity)
{ if (!SerialSetParity(args.Parity))
{ fprintf(stderr, "Line %ld: Unknown parity.\n", line->Num);
exit(10);
}
}
if (args.Protocol)
{ if (!SerialSetProtocol(args.Protocol))
{ fprintf(stderr, "Line %ld: Unknown protocol.\n", line->Num);
exit(10);
}
}
if (VerboseMode)
{ printf("%s Parameters modified:\n\n", SerialDeviceName);
SerialShowParms();
}
}
/**
*** This function shows the serial.device parameters.
**/
VOID ShowParmsFunc(struct ScriptLine *line)
{ if (!SerialDeviceName)
{ fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
exit(10);
}
printf("%s Parameters:\n\n", SerialDeviceName);
SerialShowParms();
}
/**
*** This function sends a string to the serial.device.
**/
VOID SendFunc(struct ScriptLine *line)
{ STRPTR *args;
if (!SerialDeviceName)
{ fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
exit(10);
}
if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
{ fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
exit(10);
}
if (VerboseMode)
{ printf("\nSending ");
}
for(; *args; args++)
{ STRPTR send = ParseString(*args);
SerialSend(send, strlen((char *) send));
free(send);
}
if (VerboseMode)
{ printf("\n");
}
}
/**
*** This is similar to "if".
**/
VOID DoGoto(STRPTR Label, int Num)
{ struct ScriptLine *sl;
for(sl = (struct ScriptLine *) ScriptLineList.mlh_Head;
sl->mn.mln_Succ;
sl = (struct ScriptLine *) sl->mn.mln_Succ)
{ if (sl->Label && strcmp((char *) sl->Label, (char *) Label) == 0)
{ CurrentScriptLine = (struct ScriptLine *) sl->mn.mln_Pred;
return;
}
}
fprintf(stderr, "Line %d: Unknown label.\n", Num);
exit(10);
}
VOID OnFunc(struct ScriptLine *line)
{ STRPTR ptr = line->Args;
if (strnicmp((char *) ptr, "status", 6) == 0)
{ ptr = SkipBlanks(ptr+6);
if (strnicmp((char *) ptr, "goto", 4) == 0)
{ STRPTR *labels;
int i;
if (!StrReadArgs(ptr+4, (LONG *) &labels, (STRPTR) "LABELS/M"))
{ fprintf(stderr, "Line %ld: Memory error.\n", line->Num);
exit(10);
}
for (i = -1; *labels; ++i, ++labels)
{ if (i == StatusVar)
{ DoGoto(*labels, line->Num);
return;
}
}
return;
}
}
fprintf(stderr, "Line %ld: Condition syntax.", line->Num);
exit(10);
}
/**
*** This function waits for certain strings.
**/
VOID WaitFunc(struct ScriptLine *line)
{ struct
{ STRPTR *WaitArgs;
ULONG *TimeOut;
} args;
STRPTR* parsedArgs;
LONG TimeOut;
int i = 0;
if (!SerialDeviceName)
{ fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
exit(10);
}
args.WaitArgs = NULL;
args.TimeOut = NULL;
if (!(StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M,TIMEOUT/N/K")))
{ fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
exit(10);
}
if (!args.WaitArgs)
{ fprintf(stderr, "Line %ld: Missing argument.\n", line->Num);
exit(10);
}
if (!args.TimeOut)
{ fprintf(stderr, "Line %ld: Missing timeout argument.\n", line->Num);
exit(10);
}
TimeOut = *args.TimeOut;
while (args.WaitArgs[i])
{ ++i;
}
if (!(parsedArgs = malloc(sizeof(STRPTR) * (i+1))))
{ perror("malloc");
exit(10);
}
for (i = 0; args.WaitArgs[i]; i++)
{ parsedArgs[i] = ParseString(args.WaitArgs[i]);
}
parsedArgs[i] = NULL;
StatusVar = SerialWait(parsedArgs, TimeOut);
}
/**
*** The delay function waits for a certain amount of time.
**/
VOID DelayFunc(struct ScriptLine *line)
{ ULONG tics = (int) (atof((char *) line->Args) * 50.0);
if (tics == 0)
{ fprintf(stderr, "Line %ld: Missing argument.\n", line->Num);
exit(10);
}
Delay(tics);
}
/**
*** And this is the Exit function.
**/
VOID ExitFunc(struct ScriptLine *line)
{ LONG result = atol((char *) line->Args);
exit(result);
}
/**
*** The Goto command
**/
VOID GotoFunc(struct ScriptLine *line)
{ STRPTR Label;
if (!(StrReadArgs(line->Args, (LONG *) &Label, (STRPTR) "LABEL/A")))
{ fprintf(stderr, "Line %ld: Missing argument or memory error.\n",
line->Num);
exit(10);
}
DoGoto(Label, line->Num);
}
/**
*** This function enters terminal mode.
**/
VOID TermFunc(struct ScriptLine *line)
{ struct
{ STRPTR eof;
ULONG noecho;
ULONG raw;
} args;
args.eof = NULL;
args.noecho = FALSE;
args.raw = FALSE;
if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "EOF,NOECHO/S,RAW/S"))
{ fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
exit(10);
}
if (args.eof) {
args.eof = ParseString(args.eof);
}
SerialTerminal(args.eof, !args.noecho, !args.raw);
}
/**
*** Execute external commands.
**/
VOID SystemFunc(struct ScriptLine *line)
{ STRPTR *args;
int i, result;
char *cmd;
STATIC APTR systemBuffer = NULL;
/**
*** Initialize buffer.
**/
if (!systemBuffer && !(systemBuffer = BufferCreate()))
{ perror("malloc");
exit(10);
}
BufferClear(systemBuffer);
if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
{ fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
exit(10);
}
for(i = 0; *args; ++i, ++args)
{ char *str;
if (i)
{ BufferExtend(systemBuffer, (STRPTR) " ", 1);
}
str = (char*) ParseString(*args);
BufferExtend(systemBuffer, (STRPTR) str, strlen(str));
free(str);
}
cmd = (char*) BufferBuffer(systemBuffer);
if (VerboseMode)
{ printf("Executing command: \"%s\"\n", cmd);
}
result = system(cmd);
if (result)
{ if (result > 1 && result < 10) /* Warning */
{ if (VerboseMode)
{ printf("Returned %d.\n", result);
}
}
else
{ printf("Error: Command \"%s\" returned %d.\n", cmd, result);
exit(result);
}
}
}
/**
*** Scan the buffer received by the last "wait" command.
**/
VOID ScanFunc(struct ScriptLine *line)
{ struct
{ STRPTR format;
ULONG global;
ULONG save;
} args;
ULONG flags;
args.format = NULL;
args.global = FALSE;
args.save = FALSE;
if (!(StrReadArgs(line->Args, (LONG *) &args,
(STRPTR) "FORMAT/A,GLOBAL/S,SAVE/S")))
{ fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
exit(10);
}
flags = 0;
if (args.save)
{ args.global = TRUE;
flags |= GVF_SAVE_VAR;
}
if (args.global)
{ flags |= GVF_GLOBAL_ONLY;
}
else
{ flags |= GVF_LOCAL_ONLY;
}
StatusVar = Vsscanf(SerialWaitBuffer(), args.format, flags);
}
/**
*** The SetVar command
**/
void SetVarFunc(struct ScriptLine *line)
{ struct {
STRPTR name;
STRPTR value;
ULONG global;
ULONG save;
} args;
int flags;
args.name = NULL;
args.value = NULL;
args.global = FALSE;
args.save = FALSE;
if (!(StrReadArgs(line->Args, (LONG *) &args,
(STRPTR) "NAME/A,VALUE/A,LOCALONLY/S,GLOBALONLY/S,SAVE/S")))
{ fprintf(stderr, "Line %ld: Missing argument or memory error.\n",
line->Num);
exit(10);
}
flags = 0;
if (args.save) {
flags |= GVF_SAVE_VAR;
args.global = TRUE;
}
if (args.global) {
flags |= GVF_GLOBAL_ONLY;
} else {
flags |= GVF_LOCAL_ONLY;
}
setvar(args.name, args.value, LV_VAR|flags);
}
/**
*** This is the command table.
**/
struct Command CommandTab[] =
{ { EchoFunc, (STRPTR) "echo" },
{ DeviceFunc, (STRPTR) "device" },
{ SetFunc, (STRPTR) "set" },
{ ShowParmsFunc, (STRPTR) "showparms" },
{ SendFunc, (STRPTR) "send" },
{ OnFunc, (STRPTR) "on" },
{ WaitFunc, (STRPTR) "wait" },
{ DelayFunc, (STRPTR) "delay" },
{ ExitFunc, (STRPTR) "exit" },
{ GotoFunc, (STRPTR) "goto" },
{ TermFunc, (STRPTR) "terminal" },
{ SystemFunc, (STRPTR) "system" },
{ ScanFunc, (STRPTR) "scan" },
{ SetVarFunc, (STRPTR) "setvar" },
{ NULL, NULL }
};
/**
*** This function is used to process the file. Rather easy,
*** isn't it? :-)
**/
VOID ProcessFile(VOID)
{ for(CurrentScriptLine = (struct ScriptLine *) ScriptLineList.mlh_Head;
CurrentScriptLine->mn.mln_Succ;
CurrentScriptLine = (struct ScriptLine *) CurrentScriptLine->mn.mln_Succ)
{ (*CurrentScriptLine->CommFunc)(CurrentScriptLine);
}
}
/**
*** This function reads and parses the file.
**/
VOID ParseFile(STRPTR file)
{ FILE *fp;
STATIC UBYTE buffer[4096];
ULONG linenum = 0;
ULONG success = TRUE;
if (!(fp = fopen((char *) file, "r")))
{ fprintf(stderr, "Could not open %s for reading.\n", file);
exit(10);
}
NewList((struct List *) &ScriptLineList);
while(fgets((char *) buffer, sizeof(buffer), fp))
{ ULONG len = strlen((char *) buffer);
STRPTR line;
STRPTR Label = NULL;
CommandFunc CommFunc;
++linenum;
if (buffer[len-1] != '\n')
{ fprintf(stderr, "Line %ld too long.\n", linenum);
exit(10);
}
if (!(line = malloc(len+1)))
{ perror("malloc");
exit(10);
}
strcpy((char*) line, (char*) buffer);
line = SkipBlanks(line);
/**
*** Check for a label
**/
{ STRPTR ptr = line;
if (isalpha(*ptr))
{ do
{ ++ptr;
}
while(isalnum(*ptr));
if (*ptr == ':')
{ *ptr = '\0';
Label = line;
line = SkipBlanks(ptr+1);
}
}
}
/**
*** Check for empty line or comment line
**/
if (*line == ';' || *line == '\r' || *line == '\n')
{ CommFunc = NoneFunc;
if (!Label)
{ continue;
}
}
/**
*** If no empty line: Check for command
**/
else
{ struct Command *comm;
for (comm = &CommandTab[0]; comm->Func; ++comm)
{ ULONG len = strlen((char *) comm->Name);
if (strnicmp((char *) comm->Name, (char *) line, len) == 0 &&
(line[len] == ' ' || line[len] == '\t' ||
line[len] == '\r' || line[len] == '\n'))
{ line = SkipBlanks(line+len);
CommFunc = comm->Func;
break;
}
}
if (!comm->Func)
{ fprintf(stderr, "Line %ld: Unknown command.\n", linenum);
success = FALSE;
}
}
/**
*** Allocate a new scriptline structure.
**/
{ struct ScriptLine *sl;
if (!(sl = malloc(sizeof(*sl))))
{ perror("malloc");
exit(10);
}
AddTail((struct List *) &ScriptLineList, (struct Node *) sl);
sl->Num = linenum;
sl->CommFunc = CommFunc;
sl->Args = line;
sl->Label = Label;
}
}
if (ferror(fp))
{ perror("fgets");
exit(10);
}
if (!success)
{ exit(10);
}
fclose(fp);
}
/**
*** This is the Cleanup() function, called, when the program terminates.
**/
VOID Cleanup(VOID)
{ SerialCleanup();
StrReadArgsFree();
if (MainRDArgs)
{ FreeArgs(MainRDArgs);
}
}
/**
*** This function hints about the GPL.
**/
VOID ShowGPL(FILE *fp)
{ fprintf(fp, "This program is governed by the terms and conditions of the\n");
fprintf(fp, "GNU General Public License. A copy should have come with\n");
fprintf(fp, "this distribution. (See the file COPYING.) In that license\n");
fprintf(fp, "it is made clear that you are welcome to redistribute either\n");
fprintf(fp, "verbatim or modified copies of the program and the documentation\n");
fprintf(fp, "under certain conditions. Further you are told that this program\n");
fprintf(fp, "comes with ABSOLUTELY NO WARRANTY!\n");
}
/**
*** This function displays the Usage() message.
**/
VOID Usage(VOID)
{ fprintf(stderr, "Usage: IPDial SCRIPT,DEVICE/K,PROTOCOL/K,TERMINAL/S,ECHO/S,VERBOSE/S,HELP/S\n\n");
fprintf(stderr, "\tSCRIPT: Script file to execute.\n");
fprintf(stderr, "\tDEVICE: Device to use (default serial.device)\n");
fprintf(stderr, "\tPROTOCOL: Protocol to use; XONXOFF, 7WIRE (default) or NONE)\n");
fprintf(stderr, "\tUNIT: Unit to use (default 0)\n");
fprintf(stderr, "\tECHO: Show modems replies.\n");
fprintf(stderr, "\tVERBOSE: Be verbose.\n\n");
fprintf(stderr, "\tTERMINAL: Run in terminal mode.\n");
fprintf(stderr, "\tHELP: Print this message.\n");
fprintf(stderr, "\n\n%s @ 1994 by Jochen Wiedmann\n\n", VString);
ShowGPL(stderr);
exit(5);
}
/**
*** This is main().
**/
int main(int argc, char *argv[])
{ struct
{ STRPTR file;
STRPTR device;
STRPTR protocol;
LONG *unit;
LONG *baud;
ULONG terminal;
ULONG help;
ULONG echo;
ULONG verbose;
ULONG raw;
} args;
args.file = NULL;
args.device = (STRPTR) "serial.device";
args.protocol = (STRPTR) "7wire";
args.unit = NULL;
args.baud = NULL;
args.terminal = FALSE;
args.echo = FALSE;
args.verbose = FALSE;
args.help = FALSE;
args.raw = FALSE;
if (!argc) /* No WB handling. */
{ exit(-1);
}
if (atexit(Cleanup))
{ fprintf(stderr, "Memory error.\n");
exit(20);
}
if (!(MainRDArgs = ReadArgs((STRPTR) "SCRIPT,DEVICE/K,PROTOCOL/K,"
"UNIT/K/N,BAUD/K/N,TERMINAL/S,"
"HELP/S,ECHO/S,VERBOSE/S,RAW/S",
(LONG *) &args, NULL)))
{ fprintf(stderr, "Cannot parse command line.\n");
}
if (args.help ||
(!args.file && !args.terminal))
{ Usage();
}
EchoMode = args.echo;
if (args.verbose)
{ VerboseMode = TRUE;
printf("%s @ 1994 by Jochen Wiedmann\n\n", VString);
ShowGPL(stdout);
printf("\n\n");
}
if (args.terminal)
{ SerialOpen(args.device, args.protocol, args.unit ? *args.unit : 0);
if (args.baud)
{ SerialSetBaud(*args.baud);
}
SerialTerminal(NULL, TRUE, !args.raw);
}
else if (args.file)
{ ParseFile(args.file);
ProcessFile();
}
exit(0);
}